#include "../board/sdk_project_config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//温湿度模块报文格式
#define SHT30_HUM    "R:"
#define SHT30_TEM    "RH "
#define SHT30_PREFIX "Read\r\n"
#define data_len     10

//WIFE模块AT指令
#define HC25_CODE             "+++"
#define HC25_CODE_REPORT      "ENTERED"
#define HC25_EXIT             "AT+ENTM"
#define HC25_EXIT_REPORT      "EXITED"
#define MQTT_HC25_IP          "AT+WANN"
#define MQTT_HC25_IP_REPORT   "DHCP"
#define MQTT_HC25_SSIC        "AT+WSLK"
#define MQTT_HC25_SSIC_REPORT "Sta"

//WIFE模块AT指令报文格式
#define MQTT_IP       ","
#define MQTT_IP_LEN   100
#define MQTT_SSIC_PRE ":"
#define MQTT_SSIC_END ","
#define MQTT_SSIC_LEN 100

//LED控制
#define LED_NUMBER    "led"
#define LED_ACTION    "action"
#define GPIO_PIN_HIGH 1
#define GPIO_PIN_LOW  0

//串口接收缓冲区
uint8_t buffer[BUFFER_SIZE];
uint8_t bufferldx;

//AT指令串口接收缓冲区
char Atvuffer[BUFFER_SIZE];

//串口初始化
void eswin_uart_init(void)
{
    //串口引脚初始化
    UART_DRV_Init(INST_UART2_SAMPLE, &g_stUartState_2, &g_stUart2UserConfig0);
    UART_DRV_Init(INST_UART4_SAMPLE, &g_stUartState_4, &g_stUart4UserConfig0);
    UART_DRV_Init(INST_UART5_SAMPLE, &g_stUartState_5, &g_stUart5UserConfig0);
    //设置接收回调函数
    UART_DRV_InstallRxCallback(INST_UART2_SAMPLE, RxCallback2, NULL);
    UART_DRV_InstallRxCallback(INST_UART4_SAMPLE, RxCallback4, NULL);
    UART_DRV_InstallRxCallback(INST_UART5_SAMPLE, RxCallback5, NULL);
    //设置调试串口
    setLogPort(2);
}

//封装串口接收函数
status_t receiveUartData(uint32_t intance)
{
    status_t status = STATUS_ERROR;
    uint32_t bytesRemaining;

    //清除buffer数组
    memset(buffer, 0, BUFFER_SIZE);
    //接收数据
    UART_DRV_ReceiveData(intance, buffer, 1U);
    //等待接收完成
    while (UART_DRV_GetReceiveStatus(intance, &bytesRemaining) == STATUS_BUSY)
        ;
    //获取接收状态
    status = UART_DRV_GetReceiveStatus(intance, &bytesRemaining);
    //判断接收状态
    if (status == STATUS_SUCCESS)
        return status;
    return status;
}

status_t sendmessageToHF018(int location, char *str)
{
    status_t status = STATUS_ERROR;
    uint32_t bytesRemaining;
    uint8_t sendbuffer[BUFFER_SIZE];
    return status;
}

//WIFE模块AT指令
status_t wifeATcommand(char *command, char *report)
{
    uint8_t flag    = -1;
    status_t status = STATUS_ERROR;
    memset(Atvuffer, 0, BUFFER_SIZE);
    do {
        //发送指令到WIFE模块
        UART_DRV_SendDataBlocking(INST_UART4_SAMPLE, command, strlen(command), TRANSMIT_TIMEOUT);
        //接收WIFE模块回应
        UART_DRV_ReceiveDataBlocking(INST_UART4_SAMPLE, Atvuffer, sizeof(Atvuffer), RECEIVE_AT_TIMEOUT);
        printf("wifeATcommand UART_DRV_ReceiveDataBlocking : %s \n", Atvuffer);
        //判断是否接受到需要的回应，接收不到就一直发直到接收到为止
        flag = strstr((char *)buffer, report);
        if (flag >= 0) {
            status == STATUS_SUCCESS;
            break;
        }
    } while (1);
    return status;
}

status_t mqttconnect_init()
{
    status_t status = STATUS_ERROR;
    char mqttcomment[BUFFER_SIZE];
    char ssidstr[MQTT_IP_LEN];
    char ipstr[MQTT_SSIC_LEN];
    char *star = NULL;
    char *end  = NULL;

    memset(mqttcomment, 0, BUFFER_SIZE);
    memset(ssidstr, 0, MQTT_IP_LEN);
    memset(ipstr, 0, MQTT_SSIC_LEN);
    //发送+++到WIFE模块，进入到指令模式
    wifeATcommand(HC25_CODE, HC25_CODE_REPORT);

    //发送AT+WSLK到WIFE模块，获取SSIC报文
    wifeATcommand(MQTT_HC25_SSIC, MQTT_HC25_SSIC_REPORT);
    //解析接收到的报文获取需要的SSIC
    star = strstr((char *)Atvuffer, MQTT_SSIC_PRE) + strlen(MQTT_SSIC_PRE);
    end  = strstr((char *)star, MQTT_SSIC_END);
    *end = '\0';
    memcpy(ssidstr, star, MQTT_SSIC_LEN);
    //发送AT+WANN到WIFE模块，获取IP报文
    wifeATcommand(MQTT_HC25_IP, MQTT_HC25_IP_REPORT);
    //解析接收到的报文获取需要的IP
    star = strstr((char *)Atvuffer, MQTT_IP) + strlen(MQTT_IP);
    end  = strstr((char *)Atvuffer, "\r\n");
    *end = '\0';
    memcpy(ipstr, star, MQTT_IP_LEN);

    //发送AT+ENTM到WIFE模块，退出指令模式
    wifeATcommand(HC25_EXIT, HC25_EXIT_REPORT);

    return status;
}

//获取温湿度模块的
status_t getsht30_gethumtemstr()
{
    status_t status = STATUS_ERROR;
    do {
        //发送Read\r\n到温湿度模块，获取温湿度报文
        UART_DRV_SendDataBlocking(INST_UART5_SAMPLE, SHT30_PREFIX, strlen(SHT30_PREFIX), TRANSMIT_TIMEOUT);
        //接收温湿度模块的报文
        status = receiveUartData(INST_UART5_SAMPLE);
        if (status == STATUS_SUCCESS)
            break;
    } while (1);
    return status;
}

status_t sendDataToMqttBroker(float tem, float hum)
{
    char mqttbuffer[BUFFER_SIZE];
    //组织MQTT数据报文 - JSON格式包含温湿度传感器数据
    //报文结构:
    // - services: 服务数组，包含设备提供的所有服务
    //   - service_id: 服务标识符 "wenkongdapeng"，标识温控大棚服务
    //   - properties: 属性对象，包含传感器的实时数据
    //     - temperature: 温度值(摄氏度)，保留1位小数
    //     - humidity: 湿度值(相对湿度%)，保留1位小数
    //此JSON格式符合IoT平台标准，用于设备数据上报
    snprintf(mqttbuffer, sizeof(mqttbuffer),
             "{"
             "  \"services\": ["
             "    {"
             "      \"service_id\": \"smokeDetector\","
             "      \"properties\": {\n"
             "        \"temperature\": %.1f,\n"
             "        \"humidity\": %.1f"
             "      }"
             "    }"
             "  ]"
             "}",
             tem, hum);
    //发送数据到WIFE模块
    UART_DRV_SendDataBlocking(INST_UART4_SAMPLE, mqttbuffer, strlen(mqttbuffer), TRANSMIT_TIMEOUT);
    return STATUS_SUCCESS;
}

status_t displayData(float tem, float hum)
{
    status_t status = STATUS_ERROR;
    char str[BUFFER_SIZE];
    //组织温度报文
    sprintf(str, "%.1f\xA1\xE3\x43", tem);
    //延时1000ms
    OS_DelayMs(1000);
    //组织湿度报文
    sprintf(str, "%.1fRH", hum);
    return status;
}

//在JSON字符串中查找指定键对应的值，简单辅助函数
char *find_json_value(const char *json, const char *key)
{
    // 静态缓冲区用于存储结果，需注意线程安全问题
    static char result[BUFFER_SIZE];
    char search_key[BUFFER_SIZE];

    // 构建搜索模式："key":"
    snprintf(search_key, sizeof(search_key), "\"%s\":\"", key);

    // 定位键名位置
    char *start = strstr(json, search_key);
    if (start == NULL) {
        result[0] = '\0'; // 未找到键，返回空字符串
        return result;
    }

    // 跳过键名和冒号引号，指向值的起始位置
    start += strlen(search_key);

    // 查找值的结束引号
    char *end = strchr(start, '"');
    if (end == NULL) {
        result[0] = '\0'; // 格式错误，返回空字符串
        return result;
    }

    // 计算值的长度并复制（不包含引号）
    int len = end - start;
    if (len >= BUFFER_SIZE) {
        len = BUFFER_SIZE - 1; // 防止缓冲区溢出
    }
    strncpy(result, start, len);
    result[len] = '\0'; // 手动添加字符串结束符

    return result;
}

//LED操作函数
status_t solveled(char *led_num, char *led_opt)
{
    //判断是不是LED3
    if (strncmp(led_num, "LED3", 4) == 0) {
        //判断开
        if (strncmp(led_opt, "ON", 2) == 0) {
            PINS_DRV_WritePin(PORTC, 28, GPIO_PIN_HIGH);
            return STATUS_SUCCESS;
        }
        //判断关
        else if (strncmp(led_opt, "OFF", 3) == 0) {
            PINS_DRV_WritePin(PORTC, 28, GPIO_PIN_LOW);
            return STATUS_SUCCESS;
        }
    }
    //判断是不是LED4
    else if (strncmp(led_num, "LED4", 4) == 0) {
        //判断开
        if (strncmp(led_opt, "ON", 2) == 0) {
            PINS_DRV_WritePin(PORTD, 14, GPIO_PIN_HIGH);
            return STATUS_SUCCESS;
        }
        //判断关
        else if (strncmp(led_opt, "OFF", 3) == 0) {
            PINS_DRV_WritePin(PORTD, 14, GPIO_PIN_LOW);
            return STATUS_SUCCESS;
        }
    }
    return STATUS_ERROR;
}

//解析接收到的JSON报文
status_t SolveCommand(char *str)
{
    status_t status = STATUS_ERROR;
    char combuffer[BUFFER_SIZE];
    memset(combuffer, 0, BUFFER_SIZE);
    strncpy(combuffer, str, BUFFER_SIZE - 1);
    char *led_num_opt = NULL;
    char led_num[BUFFER_SIZE];
    char led_opt[BUFFER_SIZE];

    //解析JSON报文获取LED编号
    led_num_opt = find_json_value(combuffer, LED_NUMBER);
    strncpy(led_num, led_num_opt, BUFFER_SIZE - 1);

    //解析JSON报文获取LED操作
    led_num_opt = find_json_value(combuffer, LED_ACTION);
    strncpy(led_opt, led_num_opt, BUFFER_SIZE - 1);

    //执行LED操作
    status = solveled(led_num, led_opt);
    return status;
}

//接收WIFE模块发送过来的MQTT指令
status_t MQTTcommand()
{
    status_t status = STATUS_ERROR;
    uint8_t *commandbuffer[BUFFER_SIZE];
    memset(commandbuffer, 0, BUFFER_SIZE);
    //接收数据,超时退出
    UART_DRV_ReceiveDataBlocking(INST_UART4_SAMPLE, commandbuffer, BUFFER_SIZE, RECEIVE_TIMEOUT);
    //判断是否接收到数据
    if (strncmp(commandbuffer, "\0\0\0", 3)) {
        //解析接收到的JSON报文并执行
        status = SolveCommand((char *)commandbuffer);
        return status;
    } else {
        return STATUS_ERROR;
    }
}

int main(void)
{
    status_t status;
    float tem, hum;

    //系统时钟初始化
    CLOCK_SYS_Init(g_pstClockManConfigsArr[0]);

    //引脚初始化
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_stPinmuxConfigArr);

    //串口初始化
    eswin_uart_init();
    //MQTT连接初始化
    mqttconnect_init();

    while (1) {
        //接收温湿度报文
        status = getsht30_gethumtemstr();
        //判断是否接收成功
        if (status == STATUS_SUCCESS) {
            //接收成功，解析报文获取温度和湿度
            sht30_gethumtem(buffer, &tem, &hum);
            //显示温度和湿度
            status = displayData(tem, hum);
            if (status == STATUS_SUCCESS) {
                printf("displayData OK!!\n");
            }
            //发送数据到WIFE模块
            status = sendDataToMqttBroker(tem, hum);
            if (status == STATUS_SUCCESS) {
                printf("sendDataToMqttBroker OK!!\n");
            }
        }
        //接收MQTT指令
        status = MQTTcommand();
        if (status == STATUS_ERROR) {
            printf("getMQTTcommand ERROR!\n");
        } else if (status == STATUS_SUCCESS) {
            printf("solveMQTTcommand SUCCESS!\n");
        }
    }
}

// LED操作json格式
// {
//     "led": "LED3",
//     "action": "ON"
// }
// {
//     "led": "LED3",
//     "action": "OFF"
// }
// {
//     "led": "LED4",
//     "action": "ON"
// }
// {
//     "led": "LED4",
//     "action": "OFF"
// }
